#ifndef OPAUTOPROGRAMMING
#define OPAUTOPROGRAMMING

#include "VMPFocus.hpp"
#include "operations.hpp"

#include "op $.hpp"

//Operation Text:
//Formula:
//"([^\"]|\")*"

//helper:

cText TEXT_AUTOPROGRAMMING="ap";

void funOpApPreL(ListIdentity* what){
	ParserRename(what,"$",TEXT_GETSOURCE);
};

//PreLining:

//PostLining:

//MkTree:
//====Should add Transchar function.
struct AutoProgPE{
	bool isGSFirst;
	cList<ptrText>* lsElement;
};

ptrParsedElement funOpAPMkTree(ptrText code, ptrIdentity identity, ptrParsedElement PE){
	AutoProgPE* ret=new AutoProgPE();
	if ((*code)[identity->Range.begin]==':')
		ret->isGSFirst=true;
	else
		ret->isGSFirst=false;

	ret->lsElement=new cList<ptrText>();
	int begin=identity->Range.begin+1;
	for(int i=0; i<(*identity->SubIdentities).length(); ++i){
		cRange tmp=(*identity->SubIdentities)[i]->Range;
		if (tmp.begin-begin==1)
			ret->lsElement->push(NULL);
		else{
			ret->lsElement->push(new cText(*code,begin,tmp.begin-begin));
			begin=tmp.end+1;
		};
	};
	if (begin<=identity->Range.end-1)
		ret->lsElement->push(new cText(*code,begin,identity->Range.end-begin));

	PE->Extended=(void*)ret;
	return PE;
};

//Evaluate:

sRecord funOpApEva(ptrRETNode retnode, ptrParsedElement pe, void* scope){
	AutoProgPE* prop=(AutoProgPE*)pe->Extended;
	cText tmpCode;
	/*int ptrGS=0;
	int ptrC=0;
	while (ptr*/
	if (prop->isGSFirst){
		for (int i=0; i<pe->SubElements.length(); ++i){
			tmpCode+=*getText(eval(retnode,pe->SubElements[0],0).dough);
			if (i<prop->lsElement->length() && ((*prop->lsElement)[i]))
				tmpCode+=*((*prop->lsElement)[i]);
		};
	}
	else{
		for (int i=0; i<prop->lsElement->length(); ++i){
			if ((*prop->lsElement)[i])
				tmpCode+=*((*prop->lsElement)[i]);
			if (i<pe->SubElements.length())
				tmpCode+=*getText(eval(retnode,pe->SubElements[i],0).dough);
		};
	};
	ptrParsedElement tmp=Lining(tmpCode);
	return eval(retnode,tmp,0);
	//return CreateTextDough((ptrText)(pe->Extended));
}


ptrOperation loadOpAP(){
	ptrOperation tmp=new cOperation();
	tmp->Formula="@([^\\@$]|\\@|:gs:)*@"; //@([^@\$]|\@|\\\$|:gs:)*@
	tmp->Name="@";
	tmp->onEvaluate=funOpApEva;
	tmp->onPreLining=funOpApPreL;
	tmp->onMakingTree=funOpAPMkTree;
	return tmp;
}

#endif